<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>Dungeon</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <script src="./lib/prototype.js" type="text/javascript"></script>
  <script src="./lib/scriptaculous.js" type="text/javascript"></script>
  <script type="text/javascript" language="javascript">
  // <![CDATA[

var dungeon_width = 80;
var dungeon_height = 40;
var margin = 6;


dungeon = new Array(dungeon_height)
for (j=0; j < dungeon_height; j++) {
  dungeon[j] = new Array(dungeon_width);
  for (i=0; i < dungeon_width; i++)
    dungeon[j][i] = '.';
}

function half(n) {
  return n >> 1;
}

function random_range(a,b) {
  if (a > b) {
    $('main').appendChild(Builder.node('p','error: random_range(' + a + ',' + b + ')')); 
    return -1;
  } else if (a == b) {
    return a;
  } else {
    return Math.floor(Math.random() * (b - a)) + a;
  }
}

function rectangle(x0,y0,x1,y1) {
  this.x0 = x0;
  this.y0 = y0;
  this.x1 = x1;
  this.y1 = y1;
}

function fill(rect){
  var min_j = Math.min(rect.y0, rect.y1);
  var max_j = Math.max(rect.y0, rect.y1);
  var min_i = Math.min(rect.x0, rect.x1);
  var max_i = Math.max(rect.x0, rect.x1);
  for (var j = min_j; j <= max_j; j++)
    for (var i = min_i; i <= max_i; i++)
      dungeon[j][i] = '#';
}

function split(rect) {
  if ((rect.x1 - rect.x0 < margin * 2) ||
      (rect.y1 - rect.y0 < margin * 2) ||
      (random_range(0,5) === 0)) {
    return [rect];
  } else {
    if (random_range(0,2) === 0) {
      var a = random_range(rect.y0 + margin, rect.y1 - margin);
      return [new rectangle(rect.x0, rect.y0, rect.x1, a),
	      new rectangle(rect.x0, a, rect.x1, rect.y1)].map(split).flatten();
    } else {
      var a = random_range(rect.x0 + margin, rect.x1 - margin);
      return [new rectangle(rect.x0, rect.y0, a, rect.y1),
	      new rectangle(a, rect.y0, rect.x1, rect.y1)].map(split).flatten();
    }
  }
}

function make_corrider(partitions, rooms) {
  var connect_list = new Array();
  
  for (var i = 0; i < partitions.length - 1; i++)
    connect_list.push([i, i + 1]);
  
  var connect = function(p0,p1,r0,r1) {
    if (p0.y1 == p1.y0) {
      var a = random_range(r0.x0, r0.x1);
      var b = random_range(r1.x0, r1.x1);
      fill(new rectangle(a, half(p0.y0 + p0.y1), a, p0.y1));
      fill(new rectangle(b, half(p1.y0 + p1.y1), b, p1.y0));
      fill(new rectangle(a, p0.y1, b, p1.y0));
    } else if (p0.x1 == p1.x0) {
      var a = random_range(r0.y0, r0.y1);
      var b = random_range(r1.y0, r1.y1);
      fill(new rectangle(half(r0.x0 + r0.x1), a, p0.x1, a));
      fill(new rectangle(half(r1.x0 + r1.x1), b, p1.x0, b));
      fill(new rectangle(p0.x1, a, p1.x0, b));
    }
  };
  
  connect_list.each(function(x) {connect(partitions[x[0]],partitions[x[1]],rooms[x[0]],rooms[x[1]])});
}
  
function main() {
  var partitions = split(new rectangle(0, 0, dungeon_width - 1, dungeon_height - 1));
  var rooms = partitions.map(function(p) {
    return new rectangle(p.x0 + random_range(2, half(p.x1 - p.x0) - 1),
			 p.y0 + random_range(2, half(p.y1 - p.y0) - 1),
			 p.x1 - random_range(2, half(p.x1 - p.x0) - 1),
			 p.y1 - random_range(2, half(p.y1 - p.y0) - 1));
  });
  rooms.each(fill);
  make_corrider(partitions, rooms);
  dungeon.each(function(x) {
    var elt = document.createElement('code');
    elt.appendChild(document.createTextNode(x.join('')));
    $('main').appendChild(elt);
    $('main').appendChild(document.createElement('br'));
  });
}

window.onload = main;

  // ]]>
  </script>
</head>
<div id="main"></div>
</body>
</html>
